home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume6 / rpc2 / part03 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  52.5 KB

  1. Subject:  v06i091:  Sun RPC Source (rpc2), Part03/11
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: cca!SUN.COM!marks (Mark Stein)
  6. Mod.sources: Volume 6, Issue 91
  7. Archive-name: rpc2/Part03
  8.  
  9. [  All I did was verity that the shar files unpacked correctly.  -r$  ]
  10.  
  11. Sun RPC source (part 3 of 11).  This software package contains code
  12. and documentation for Revision 3.0 of the Sun Remote Procedure Call
  13. library.  In addition, a beta version of the XDR/RPC protocol compiler
  14. is included.  Comments about this latest release may be mailed to
  15. sun!rpc or rpc@sun.com.
  16.  
  17. Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  18. unrestricted use provided that this legend is included on all tape
  19. media and as a part of the software program in whole or part.  Users
  20. may copy or modify Sun RPC without charge, but are not authorized to
  21. license or distribute it to anyone else except as part of a product or
  22. program developed by the user.
  23.  
  24. - - - - - - - - - C U T - H E R E - - - - - - - - - - - - - - - - - -
  25. #! /bin/sh
  26. # This is a shell archive, meaning:
  27. # 1. Remove everything above the #! /bin/sh line.
  28. # 2. Save the resulting text in a file.
  29. # 3. Execute the file with /bin/sh (not csh) to create:
  30. #    rpc/doc/xdr.spec.p1
  31. # This archive created: Mon Jul 14 16:55:03 1986
  32. export PATH; PATH=/bin:/usr/bin:$PATH
  33. for d in rpc rpc/doc rpc/rpclib rpc/tools rpc/toys rpc/rpclib/profiled rpc/rpcgen rpc/rpcgen/test
  34. do
  35.     if test ! -d $d
  36.     then
  37.         echo "shar: Making directory $d"
  38.         mkdir $d
  39.         chmod 755 $d
  40.     fi
  41. done
  42. echo shar: "extracting 'rpc/doc/xdr.spec.p1'" '(49809 characters)'
  43. if test -f 'rpc/doc/xdr.spec.p1'
  44. then
  45.     echo shar: "will not over-write existing file 'rpc/doc/xdr.spec.p1'"
  46. else
  47. sed 's/^X//' << \SHAR_EOF > 'rpc/doc/xdr.spec.p1'
  48. X.\" @(#)c3.xdr.spec 1.1 86/02/25 SMI; for 3.0 FCS
  49. X.PL RIGHT
  50. X.EQ
  51. Xdelim $$
  52. X.EN
  53. X.TL
  54. XExternal Data Representation
  55. X.br
  56. XProtocol Specification
  57. X.bp
  58. X.NH
  59. XIntroduction
  60. X.LP
  61. XThis manual describes library routines that allow a C programmer to 
  62. Xdescribe arbitrary data structures in a machine-independent fashion.
  63. XThe eXternal Data Representation (XDR) standard
  64. Xis the backbone of Sun's Remote Procedure Call package,
  65. Xin the sense that data for remote procedure calls
  66. Xis transmitted using the standard.
  67. XXDR library routines should be used to transmit data
  68. Xthat is accessed (read or written) by more than one type of machine.
  69. X.LP
  70. XThis manual contains a description of XDR library routines,
  71. Xa guide to accessing currently available XDR streams,
  72. Xinformation on defining new streams and data types,
  73. Xand a formal definition of the XDR standard.
  74. XXDR was designed to work across different languages,
  75. Xoperating systems, and machine architectures.
  76. XMost users (particularly RPC users)
  77. Xonly need the information in sections 2 and 3 of this document.
  78. XProgrammers wishing to implement RPC and XDR on new machines
  79. Xwill need the information in sections 4 through 6.
  80. XAdvanced topics, not necessary for all implementations,
  81. Xare covered in section 7.
  82. X.LP
  83. XOn Sun systems,
  84. XC programs that want to use XDR routines
  85. Xmust include the file
  86. X.LW <rpc/rpc.h> ,
  87. Xwhich contains all the necessary interfaces to the XDR system.
  88. XSince the C library
  89. X.LW libc.a
  90. Xcontains all the XDR routines,
  91. Xcompile as normal.
  92. X.LS
  93. X% \f(LBcc\0\fIprogram\fP.c\fL
  94. X.Lf
  95. X.NH 2
  96. XJustification
  97. X.LP
  98. XConsider the following two programs,
  99. X.LW writer :
  100. X.LS
  101. X#include <stdio.h>
  102. X.sp.5
  103. Xmain()            /* writer.c */
  104. X{
  105. X    long i;
  106. X.sp.5
  107. X    for (i = 0; i < 8; i++) {
  108. X        if (fwrite((char *)&i, sizeof(i), 1, stdout) != 1) {
  109. X            fprintf(stderr, "failed!\en");
  110. X            exit(1);
  111. X        }
  112. X    }
  113. X}
  114. X.Lf
  115. Xand
  116. X.LW reader :
  117. X.LS
  118. X#include <stdio.h>
  119. X.sp.5
  120. Xmain()            /* reader.c */
  121. X{
  122. X    long i, j;
  123. X.sp.5
  124. X    for (j = 0; j < 8; j++) {
  125. X        if (fread((char *)&i, sizeof (i), 1, stdin) != 1) {
  126. X            fprintf(stderr, "failed!\en");
  127. X            exit(1);
  128. X        }
  129. X        printf("%ld ", i);
  130. X    }
  131. X    printf("\en");
  132. X}
  133. X.Lf
  134. XThe two programs appear to be portable, because
  135. X(a) they pass
  136. X.LW lint
  137. Xchecking, and
  138. X(b) they exhibit the same behavior when executed
  139. Xon two different hardware architectures, a Sun and a VAX.
  140. X.LP
  141. XPiping the output of the
  142. X.LW writer
  143. Xprogram to the
  144. X.LW reader
  145. Xprogram gives identical results on a Sun or a VAX.\(dd
  146. X.FS \(dd
  147. XVAX is a trademark of Digital Equipment Corporation.
  148. X.FE
  149. X.LS
  150. Xsun% writer | reader
  151. X0 1 2 3 4 5 6 7
  152. Xsun%
  153. X.Lf
  154. X.LS
  155. Xvax% writer | reader
  156. X0 1 2 3 4 5 6 7
  157. Xvax%
  158. X.Lf
  159. XWith the advent of local area networks and Berkeley's 4.2 BSD
  160. X.UX
  161. Xcame the concept of ``network pipes'' \(em
  162. Xa process produces data on one machine,
  163. Xand a second process consumes data on another machine.
  164. XA network pipe can be constructed with
  165. X.LW writer
  166. Xand
  167. X.LW reader .
  168. XHere are the results if the first produces data on a Sun,
  169. Xand the second consumes data on a VAX.
  170. X.LS
  171. Xsun% writer | rsh vax reader
  172. X0 16777216 33554432 50331648 67108864 83886080 100663296
  173. X117440512
  174. Xsun%
  175. X.Lf
  176. XIdentical results can be obtained by executing
  177. X.LW writer
  178. Xon the VAX and
  179. X.LW reader
  180. Xon the Sun.
  181. XThese results occur because the byte ordering
  182. Xof long integers differs between the VAX and the Sun,
  183. Xeven though word size is the same.
  184. XNote that $16777216$ is $2 sup 24$ \(em
  185. Xwhen four bytes are reversed, the 1 winds up in the 24th bit.
  186. X.LP
  187. XWhenever data is shared by two or more machine types,
  188. Xthere is a need for portable data.
  189. XPrograms can be made data-portable by replacing the
  190. X.LW read()
  191. Xand
  192. X.LW write()
  193. Xcalls with calls to an XDR library routine
  194. X.LW xdr_long() ,
  195. Xa filter that knows the standard representation
  196. Xof a long integer in its external form.
  197. XHere are the revised versions of
  198. X.LW writer :
  199. X.LS
  200. X#include <stdio.h>
  201. X#include <rpc/rpc.h>    /* xdr is a sub-library of rpc */
  202. X.sp.5
  203. Xmain()        /* writer.c */
  204. X{
  205. X    XDR xdrs;
  206. X    long i;
  207. X.sp.5
  208. X    xdrstdio_create(&xdrs, stdout, XDR_ENCODE);
  209. X    for (i = 0; i < 8; i++) {
  210. X        if (!xdr_long(&xdrs, &i)) {
  211. X            fprintf(stderr, "failed!\en");
  212. X            exit(1);
  213. X        }
  214. X    }
  215. X}
  216. X.Lf
  217. Xand
  218. X.LW reader :
  219. X.LS
  220. X#include <stdio.h>
  221. X#include <rpc/rpc.h>    /* xdr is a sub-library of rpc */
  222. X.sp.5
  223. Xmain()        /* reader.c */
  224. X{
  225. X    XDR xdrs;
  226. X    long i, j;
  227. X.sp.5
  228. X    xdrstdio_create(&xdrs, stdin, XDR_DECODE);
  229. X    for (j = 0; j < 8; j++) {
  230. X        if (!xdr_long(&xdrs, &i)) {
  231. X            fprintf(stderr, "failed!\en");
  232. X            exit(1);
  233. X        }
  234. X        printf("%ld ", i);
  235. X    }
  236. X    printf("\en");
  237. X}
  238. X.Lf
  239. XThe new programs were executed on a Sun,
  240. Xon a VAX, and from a Sun to a VAX;
  241. Xthe results are shown below.
  242. X.LS
  243. Xsun% writer | reader
  244. X0 1 2 3 4 5 6 7
  245. Xsun%
  246. X.Lf
  247. X.LS
  248. Xvax% writer | reader
  249. X0 1 2 3 4 5 6 7
  250. Xvax%
  251. X.Lf
  252. X.LS
  253. Xsun% writer | rsh vax reader
  254. X0 1 2 3 4 5 6 7
  255. Xsun%
  256. X.Lf
  257. XDealing with integers is just the tip of the portable-data iceberg.
  258. XArbitrary data structures present portability problems,
  259. Xparticularly with respect to alignment and pointers.
  260. XAlignment on word boundaries may cause the
  261. Xsize of a structure to vary from machine to machine.
  262. XPointers are convenient to use,
  263. Xbut have no meaning outside the machine where they are defined.
  264. X.NH 2
  265. XThe XDR Library
  266. X.LP
  267. XThe XDR library solves data portability problems.
  268. XIt allows you to write and read arbitrary C constructs
  269. Xin a consistent, specified, well-documented manner.
  270. XThus, it makes sense to use the library even when the data
  271. Xis not shared among machines on a network.
  272. X.LP
  273. XThe XDR library has filter routines for
  274. Xstrings (null-terminated arrays of bytes),
  275. Xstructures, unions, and arrays, to name a few.
  276. XUsing more primitive routines,
  277. Xyou can write your own specific XDR routines
  278. Xto describe arbitrary data structures,
  279. Xincluding elements of arrays, arms of unions,
  280. Xor objects pointed at from other structures.
  281. XThe structures themselves may contain arrays of arbitrary elements,
  282. Xor pointers to other structures.
  283. X.LP
  284. XLet's examine the two programs more closely.
  285. XThere is a family of XDR stream creation routines
  286. Xin which each member treats the stream of bits differently.
  287. XIn our example, data is manipulated using standard I/O routines,
  288. Xso we use
  289. X.LW xdrstdio_create() .
  290. XThe parameters to XDR stream creation routines
  291. Xvary according to their function.
  292. XIn our example,
  293. X.LW xdrstdio_create()
  294. Xtakes a pointer to an XDR structure that it initializes,
  295. Xa pointer to a
  296. X.LW FILE
  297. Xthat the input or output is performed on, and the operation.
  298. XThe operation may be
  299. X.LW XDR_ENCODE
  300. Xfor serializing in the
  301. X.LW writer
  302. Xprogram, or
  303. X.LW XDR_DECODE
  304. Xfor deserializing in the
  305. X.LW reader
  306. Xprogram.
  307. X.LP
  308. XNote: RPC clients never need to create XDR streams;
  309. Xthe RPC system itself creates these streams,
  310. Xwhich are then passed to the clients.
  311. X.LP
  312. XThe
  313. X.LW xdr_long()
  314. Xprimitive is characteristic of most XDR library 
  315. Xprimitives and all client XDR routines.
  316. XFirst, the routine returns
  317. X.LW FALSE
  318. X(0) if it fails, and
  319. X.LW TRUE
  320. X(1) if it succeeds.
  321. XSecond, for each data type,
  322. X.LW xxx ,
  323. Xthere is an associated XDR routine of the form:
  324. X.LS
  325. Xxdr_xxx(xdrs, fp)
  326. X    XDR *xdrs;
  327. X    xxx *fp;
  328. X{
  329. X}
  330. X.Lf
  331. XIn our case,
  332. X.LW xxx
  333. Xis long, and the corresponding XDR routine is
  334. Xa primitive,
  335. X.LW xdr_long . 
  336. XThe client could also define an arbitrary structure
  337. X.LW xxx
  338. Xin which case the client would also supply the routine
  339. X.LW xdr_xxx ,
  340. Xdescribing each field by calling XDR routines
  341. Xof the appropriate type.
  342. XIn all cases the first parameter,
  343. X.LW xdrs
  344. Xcan be treated as an opaque handle,
  345. Xand passed to the primitive routines.
  346. X.LP
  347. XXDR routines are direction independent;
  348. Xthat is, the same routines are called to serialize or deserialize data.
  349. XThis feature is critical to software engineering of portable data.
  350. XThe idea is to call the same routine for either operation \(em
  351. Xthis almost guarantees that serialized data can also be deserialized.
  352. XOne routine is used by both producer and consumer of networked data.
  353. XThis is implemented by always passing the address
  354. Xof an object rather than the object itself \(em
  355. Xonly in the case of deserialization is the object modified.
  356. XThis feature is not shown in our trivial example,
  357. Xbut its value becomes obvious when nontrivial data structures
  358. Xare passed among machines.
  359. XIf needed, you can obtain the direction of the XDR operation.
  360. XSee section 3.7 for details.
  361. X.LP
  362. XLet's look at a slightly more complicated example.
  363. XAssume that a person's gross assets and liabilities
  364. Xare to be exchanged among processes.
  365. XAlso assume that these values are important enough
  366. Xto warrant their own data type:
  367. X.LS
  368. Xstruct gnumbers {
  369. X    long g_assets;
  370. X    long g_liabilities;
  371. X};
  372. X.Lf
  373. XThe corresponding XDR routine describing this structure would be:
  374. X.LS
  375. Xbool_t          /* TRUE is success, FALSE is failure */
  376. Xxdr_gnumbers(xdrs, gp)
  377. X    XDR *xdrs;
  378. X    struct gnumbers *gp;
  379. X{
  380. X    if (xdr_long(xdrs, &gp->g_assets) &&
  381. X        xdr_long(xdrs, &gp->g_liabilities))
  382. X        return(TRUE);
  383. X    return(FALSE);
  384. X}
  385. X.Lf
  386. XNote that the parameter
  387. X.LW xdrs
  388. Xis never inspected or modified;
  389. Xit is only passed on to the subcomponent routines.
  390. XIt is imperative to inspect the return value of each XDR routine call,
  391. Xand to give up immediately and return
  392. X.LW FALSE
  393. Xif the subroutine fails.
  394. X.LP
  395. XThis example also shows that the type
  396. X.LW bool_t
  397. Xis declared as an integer whose only values are
  398. X.LW TRUE
  399. X(1) and
  400. X.LW FALSE
  401. X(0).  This document uses the following definitions:
  402. X.LS
  403. X#define bool_t    int
  404. X#define TRUE    1
  405. X#define FALSE    0
  406. X.sp.5
  407. X#define enum_t int    /* enum_t used for generic enums */
  408. X.Lf
  409. X.LP
  410. XKeeping these conventions in mind,
  411. X.LW xdr_gnumbers()
  412. Xcan be rewritten as follows:
  413. X.LS
  414. Xxdr_gnumbers(xdrs, gp)
  415. X    XDR *xdrs;
  416. X    struct gnumbers *gp;
  417. X{
  418. X    return(xdr_long(xdrs, &gp->g_assets) &&
  419. X        xdr_long(xdrs, &gp->g_liabilities));
  420. X}
  421. X.Lf
  422. XThis document uses both coding styles.
  423. X.bp
  424. X.NH
  425. XXDR Library Primitives
  426. X.LP
  427. XThis section gives a synopsis of each XDR primitive.
  428. XIt starts with basic data types and moves on to constructed data types.
  429. XFinally, XDR utilities are discussed.
  430. XThe interface to these primitives
  431. Xand utilities is defined in the include file
  432. X.LW <rpc/xdr.h> ,
  433. Xautomatically included by
  434. X.LW <rpc/rpc.h> .
  435. X.NH 2
  436. XNumber Filters
  437. X.LP
  438. XThe XDR library provides primitives to translate between numbers
  439. Xand their corresponding external representations.
  440. XPrimitives cover the set of numbers in:
  441. X.EQ
  442. X[signed, unsigned] * [short, int, long]
  443. X.EN
  444. XSpecifically, the six primitives are:
  445. X.LS
  446. Xbool_t xdr_int(xdrs, ip)
  447. X    XDR *xdrs;
  448. X    int *ip;
  449. X.sp.5
  450. Xbool_t xdr_u_int(xdrs, up)
  451. X    XDR *xdrs;
  452. X    unsigned *up;
  453. X.sp.5
  454. Xbool_t xdr_long(xdrs, lip)
  455. X    XDR *xdrs;
  456. X    long *lip;
  457. X.sp.5
  458. Xbool_t xdr_u_long(xdrs, lup)
  459. X    XDR *xdrs;
  460. X    u_long *lup;
  461. X.sp.5
  462. Xbool_t xdr_short(xdrs, sip)
  463. X    XDR *xdrs;
  464. X    short *sip;
  465. X.sp.5
  466. Xbool_t xdr_u_short(xdrs, sup)
  467. X    XDR *xdrs;
  468. X    u_short *sup;
  469. X.Lf
  470. XThe first parameter,
  471. X.LW xdrs ,
  472. Xis an XDR stream handle.
  473. XThe second parameter is the address of the number
  474. Xthat provides data to the stream or receives data from it.
  475. XAll routines return
  476. X.LW TRUE
  477. Xif they complete successfully, and
  478. X.LW FALSE
  479. Xotherwise.
  480. X.NH 2
  481. XFloating Point Filters
  482. X.LP
  483. XThe XDR library also provides primitive routines
  484. Xfor C's floating point types:
  485. X.LS
  486. Xbool_t xdr_float(xdrs, fp)
  487. X    XDR *xdrs;
  488. X    float *fp;
  489. X.sp.5
  490. Xbool_t xdr_double(xdrs, dp)
  491. X    XDR *xdrs;
  492. X    double *dp;
  493. X.Lf
  494. XThe first parameter,
  495. X.LW xdrs
  496. Xis an XDR stream handle.
  497. XThe second parameter is the address
  498. Xof the floating point number that provides data to the stream
  499. Xor receives data from it.
  500. XAll routines return
  501. X.LW TRUE
  502. Xif they complete successfully, and
  503. X.LW FALSE
  504. Xotherwise.
  505. X.LP
  506. XNote: Since the numbers are represented in IEEE floating point,
  507. Xroutines may fail when decoding a valid IEEE representation
  508. Xinto a machine-specific representation, or vice-versa.
  509. X.NH 2
  510. XEnumeration Filters
  511. X.LP
  512. XThe XDR library provides a primitive for generic enumerations.
  513. XThe primitive assumes that a C
  514. X.LW enum
  515. Xhas the same representation inside the machine as a C integer.
  516. XThe boolean type is an important instance of the
  517. X.LW enum .
  518. XThe external representation of a boolean is always one
  519. X.LW TRUE ) (
  520. Xor zero
  521. X.LW FALSE ). (
  522. X.LS
  523. X#define bool_t    int
  524. X#define FALSE    0
  525. X#define TRUE    1
  526. X.sp.5
  527. X#define enum_t int
  528. X.sp.5
  529. Xbool_t xdr_enum(xdrs, ep)
  530. X    XDR *xdrs;
  531. X    enum_t *ep;
  532. X.sp.5
  533. Xbool_t xdr_bool(xdrs, bp)
  534. X    XDR *xdrs;
  535. X    bool_t *bp;
  536. X.Lf
  537. XThe second parameters
  538. X.LW ep
  539. Xand
  540. X.LW bp
  541. Xare addresses of the associated type
  542. Xthat provides data to, or receives data from, the stream
  543. X.LW xdrs .
  544. XThe routines return
  545. X.LW TRUE
  546. Xif they complete successfully, and
  547. X.LW FALSE
  548. Xotherwise.
  549. X.NH 2
  550. XNo Data
  551. X.LP
  552. XOccasionally, an XDR routine must be supplied to the RPC system,
  553. Xeven when no data is passed or required.
  554. XThe library provides such a routine:
  555. X.LS
  556. Xbool_t xdr_void();  /* always returns TRUE */
  557. X.Lf
  558. X.NH 2
  559. XConstructed Data Type Filters
  560. X.LP
  561. XConstructed or compound data type primitives
  562. Xrequire more parameters and perform more complicated functions
  563. Xthen the primitives discussed above.
  564. XThis section includes primitives for
  565. Xstrings, arrays, unions, and pointers to structures.
  566. X.LP
  567. XConstructed data type primitives may use memory management.
  568. XIn many cases, memory is allocated when deserializing data with
  569. X.LW XDR_DECODE .
  570. XTherefore, the XDR package must provide means to deallocate memory.
  571. XThis is done by an XDR operation,
  572. X.LW XDR_FREE .
  573. XTo review, the three XDR directional operations are
  574. X.LW XDR_ENCODE ,
  575. X.LW XDR_DECODE ,
  576. Xand
  577. X.LW XDR_FREE .
  578. X.NH 3
  579. XStrings
  580. X.LP
  581. XIn C, a string is defined as a sequence of bytes
  582. Xterminated by a null byte,
  583. Xwhich is not considered when calculating string length.
  584. XHowever, when a string is passed or manipulated,
  585. Xa pointer to it is employed.
  586. XTherefore, the XDR library defines a string to be a
  587. X.LW "char *" ,
  588. Xand not a sequence of characters.
  589. XThe external representation of a string is drastically different
  590. Xfrom its internal representation.
  591. XExternally, strings are represented as
  592. Xsequences of ASCII characters,
  593. Xwhile internally, they are represented with character pointers.
  594. XConversion between the two representations
  595. Xis accomplished with the routine
  596. X.LW xdr_string() :
  597. X.LS
  598. Xbool_t xdr_string(xdrs, sp, maxlength)
  599. X    XDR *xdrs;
  600. X    char **sp;
  601. X    u_int maxlength;
  602. X.Lf
  603. XThe first parameter
  604. X.LW xdrs
  605. Xis the XDR stream handle.
  606. XThe second parameter
  607. X.LW sp
  608. Xis a pointer to a string (type
  609. X.LW "char **" ).
  610. XThe third parameter
  611. X.LW maxlength
  612. Xspecifies the maximum number of bytes allowed during encoding or decoding;
  613. Xits value is usually specified by a protocol.
  614. XFor example, a protocol specification may say
  615. Xthat a file name may be no longer than 255 characters.
  616. XThe routine returns
  617. X.LW FALSE
  618. Xif the number of characters exceeds
  619. X.LW maxlength ,
  620. Xand
  621. X.LW TRUE
  622. Xif it doesn't.
  623. X.LP
  624. XThe behavior of
  625. X.LW xdr_string()
  626. Xis similar to the behavior of other routines
  627. Xdiscussed in this section.  The direction
  628. X.LW XDR_ENCODE
  629. Xis easiest to understand.  The parameter
  630. X.LW sp
  631. Xpoints to a string of a certain length;
  632. Xif it does not exceed
  633. X.LW maxlength ,
  634. Xthe bytes are serialized.
  635. X.LP
  636. XThe effect of deserializing a string is subtle.
  637. XFirst the length of the incoming string is determined;
  638. Xit must not exceed
  639. X.LW maxlength .
  640. XNext
  641. X.LW sp
  642. Xis dereferenced; if the the value is
  643. X.LW NULL ,
  644. Xthen a string of the appropriate length is allocated and
  645. X.LW *sp
  646. Xis set to this string.
  647. XIf the original value of
  648. X.LW *sp
  649. Xis non-null, then the XDR package assumes
  650. Xthat a target area has been allocated,
  651. Xwhich can hold strings no longer than
  652. X.LW maxlength .
  653. XIn either case, the string is decoded into the target area.
  654. XThe routine then appends a null character to the string.
  655. X.LP
  656. XIn the
  657. X.LW XDR_FREE
  658. Xoperation, the string is obtained by dereferencing
  659. X.LW sp .
  660. XIf the string is not
  661. X.LW NULL ,
  662. Xit is freed and
  663. X.LW *sp
  664. Xis set to
  665. X.LW NULL .
  666. XIn this operation,
  667. X.LW xdr_string
  668. Xignores the
  669. X.LW maxlength
  670. Xparameter.
  671. X.NH 3
  672. XByte Arrays
  673. X.LP
  674. XOften variable-length arrays of bytes are preferable to strings.
  675. XByte arrays differ from strings in the following three ways: 
  676. X1) the length of the array (the byte count) is explicitly
  677. Xlocated in an unsigned integer,
  678. X2) the byte sequence is not terminated by a null character, and
  679. X3) the external representation of the bytes is the same as their
  680. Xinternal representation.
  681. XThe primitive
  682. X.LW xdr_bytes()
  683. Xconverts between the internal and external
  684. Xrepresentations of byte arrays:
  685. X.LS
  686. Xbool_t xdr_bytes(xdrs, bpp, lp, maxlength)
  687. X    XDR *xdrs;
  688. X    char **bpp;
  689. X    u_int *lp;
  690. X    u_int maxlength;
  691. X.Lf
  692. XThe usage of the first, second and fourth parameters
  693. Xare identical to the first, second and third parameters of
  694. X.LW xdr_string() ,
  695. Xrespectively.
  696. XThe length of the byte area is obtained by dereferencing
  697. X.LW lp
  698. Xwhen serializing;
  699. X.LW *lp
  700. Xis set to the byte length when deserializing.
  701. X.NH 3
  702. XArrays
  703. X.LP
  704. XThe XDR library package provides a primitive
  705. Xfor handling arrays of arbitrary elements.
  706. XThe
  707. X.LW xdr_bytes()
  708. Xroutine treats a subset of generic arrays,
  709. Xin which the size of array elements is known to be 1,
  710. Xand the external description of each element is built-in.
  711. XThe generic array primitive,
  712. X.LW xdr_array()
  713. Xrequires parameters identical to those of
  714. X.LW xdr_bytes()
  715. Xplus two more:
  716. Xthe size of array elements,
  717. Xand an XDR routine to handle each of the elements.
  718. XThis routine is called to encode or decode
  719. Xeach element of the array.
  720. X.LS
  721. Xbool_t
  722. Xxdr_array(xdrs, ap, lp, maxlength, elementsiz, xdr_element)
  723. X    XDR *xdrs;
  724. X    char **ap;
  725. X    u_int *lp;
  726. X    u_int maxlength;
  727. X    u_int elementsiz;
  728. X    bool_t (*xdr_element)();
  729. X.Lf
  730. XThe parameter
  731. X.LW ap
  732. Xis the address of the pointer to the array.
  733. XIf
  734. X.LW *ap
  735. Xis
  736. X.LW NULL
  737. Xwhen the array is being deserialized,
  738. XXDR allocates an array of the appropriate size and sets
  739. X.LW *ap
  740. Xto that array.
  741. XThe element count of the array is obtained from
  742. X.LW *lp
  743. Xwhen the array is serialized;
  744. X.LW *lp
  745. Xis set to the array length when the array is deserialized. 
  746. XThe parameter
  747. X.LW maxlength
  748. Xis the maximum number of elements that the array is allowed to have;
  749. X.LW elementsiz
  750. Xis the byte size of each element of the array
  751. X(the C function
  752. X.LW sizeof()
  753. Xcan be used to obtain this value).
  754. XThe routine
  755. X.LW xdr_element
  756. Xis called to serialize, deserialize, or free
  757. Xeach element of the array.
  758. X.NH 4
  759. XExamples
  760. X.LP
  761. XBefore defining more constructed data types,
  762. Xit is appropriate to present three examples.
  763. X.LP
  764. X.I "Example A"
  765. X.LP
  766. XA user on a networked machine can be identified by 
  767. X(a) the machine name, such as
  768. X.LW krypton :
  769. Xsee
  770. X.I gethostname (3);
  771. X(b) the user's UID: see
  772. X.I geteuid (2);
  773. Xand (c) the group numbers to which the user belongs: see
  774. X.I getgroups (2).
  775. XA structure with this information and its associated XDR routine
  776. Xcould be coded like this:
  777. X.LS
  778. Xstruct netuser {
  779. X    char    *nu_machinename;
  780. X    int     nu_uid;
  781. X    u_int    nu_glen;
  782. X    int     *nu_gids;
  783. X};
  784. X#define NLEN 255    /* machine names < 256 chars */
  785. X#define NGRPS 20    /* user can't be in > 20 groups */
  786. X.sp.5
  787. Xbool_t
  788. Xxdr_netuser(xdrs, nup)
  789. X    XDR *xdrs;
  790. X    struct netuser *nup;
  791. X{
  792. X    return(xdr_string(xdrs, &nup->nu_machinename, NLEN) &&
  793. X        xdr_int(xdrs, &nup->nu_uid) &&
  794. X        xdr_array(xdrs, &nup->nu_gids, &nup->nu_glen, NGRPS,
  795. X        sizeof (int), xdr_int));
  796. X}
  797. X.Lf
  798. X.LP
  799. X.I "Example B"
  800. X.LP
  801. XA party of network users could be implemented
  802. Xas an array of
  803. X.LW netuser
  804. Xstructure.
  805. XThe declaration and its associated XDR routines
  806. Xare as follows:
  807. X.LS
  808. Xstruct party {
  809. X    u_int p_len;
  810. X    struct netuser *p_nusers;
  811. X};
  812. X#define PLEN 500 /* max number of users in a party */
  813. X.sp.5
  814. Xbool_t
  815. Xxdr_party(xdrs, pp)
  816. X    XDR *xdrs;
  817. X    struct party *pp;
  818. X{
  819. X    return(xdr_array(xdrs, &pp->p_nusers, &pp->p_len, PLEN,
  820. X        sizeof (struct netuser), xdr_netuser));
  821. X}
  822. X.Lf
  823. X.LP
  824. X.I "Example C"
  825. X.LP
  826. XThe well-known parameters to
  827. X.LW main() ,
  828. X.LW argc
  829. Xand
  830. X.LW argv
  831. Xcan be combined into a structure.
  832. XAn array of these structures can make up a history of commands.
  833. XThe declarations and XDR routines might look like:
  834. X.LS no
  835. Xstruct cmd {
  836. X    u_int c_argc;
  837. X    char **c_argv;
  838. X};
  839. X#define ALEN 1000    /* args cannot be > 1000 chars */
  840. X#define NARGC 100    /* commands cannot have > 100 args */
  841. X.sp.5
  842. Xstruct history {
  843. X    u_int h_len;
  844. X    struct cmd *h_cmds;
  845. X};
  846. X#define NCMDS 75  /* history is no more than 75 commands */
  847. X.sp.5
  848. Xbool_t
  849. Xxdr_wrap_string(xdrs, sp)
  850. X    XDR *xdrs;
  851. X    char **sp;
  852. X{
  853. X    return(xdr_string(xdrs, sp, ALEN));
  854. X}
  855. X.sp.5
  856. Xbool_t
  857. Xxdr_cmd(xdrs, cp)
  858. X    XDR *xdrs;
  859. X    struct cmd *cp;
  860. X{
  861. X    return(xdr_array(xdrs, &cp->c_argv, &cp->c_argc, NARGC,
  862. X        sizeof (char *), xdr_wrap_string));
  863. X}
  864. X.sp.5
  865. Xbool_t
  866. Xxdr_history(xdrs, hp)
  867. X    XDR *xdrs;
  868. X    struct history *hp;
  869. X{
  870. X    return(xdr_array(xdrs, &hp->h_cmds, &hp->h_len, NCMDS,
  871. X        sizeof (struct cmd), xdr_cmd));
  872. X}
  873. X.Lf
  874. XThe most confusing part of this example is that the routine
  875. X.LW xdr_wrap_string()
  876. Xis needed to package the
  877. X.LW xdr_string()
  878. Xroutine, because the implementation of
  879. X.LW xdr_array()
  880. Xonly passes two parameters to the array element description routine;
  881. X.LW xdr_wrap_string()
  882. Xsupplies the third parameter to
  883. X.LW xdr_string() .
  884. X.LP
  885. XBy now the recursive nature of the XDR library should be obvious.
  886. XLet's continue with more constructed data types.
  887. X.NH 3
  888. XOpaque Data
  889. X.LP
  890. XIn some protocols, handles are passed from a server to client.
  891. XThe client passes the handle back to the server at some later time.
  892. XHandles are never inspected by clients;
  893. Xthey are obtained and submitted.
  894. XThat is to say, handles are opaque.
  895. XThe primitive
  896. X.LW xdr_opaque()
  897. Xis used for describing fixed sized, opaque bytes.
  898. X.LS
  899. Xbool_t xdr_opaque(xdrs, p, len)
  900. X    XDR *xdrs;
  901. X    char *p;
  902. X    u_int len;
  903. X.Lf
  904. XThe parameter
  905. X.LW p
  906. Xis the location of the bytes;
  907. X.LW len
  908. Xis the number of bytes in the opaque object.
  909. XBy definition, the actual data
  910. Xcontained in the opaque object are not machine portable.
  911. X.NH 3
  912. XFixed Sized Arrays
  913. X.LP
  914. XThe XDR library does not provide a primitive for fixed-length arrays
  915. X(the primitive
  916. X.LW xdr_array()
  917. Xis for varying-length arrays).
  918. XExample A could be rewritten to use fixed-sized arrays
  919. Xin the following fashion:
  920. X.LS no
  921. X#define NLEN 255    /* machine names must be < 256 chars */
  922. X#define NGRPS 20    /* user can't belong to > 20 groups */
  923. X.sp.5
  924. Xstruct netuser {
  925. X    char *nu_machinename;
  926. X    int nu_uid;
  927. X    int nu_gids[NGRPS];
  928. X};
  929. X.sp.5
  930. Xbool_t
  931. Xxdr_netuser(xdrs, nup)
  932. X    XDR *xdrs;
  933. X    struct netuser *nup;
  934. X{
  935. X    int i;
  936. X.sp.5
  937. X    if (!xdr_string(xdrs, &nup->nu_machinename, NLEN))
  938. X        return(FALSE);
  939. X    if (!xdr_int(xdrs, &nup->nu_uid))
  940. X        return(FALSE);
  941. X    for (i = 0; i < NGRPS; i++) {
  942. X        if (!xdr_int(xdrs, &nup->nu_gids[i]))
  943. X            return(FALSE);
  944. X    }
  945. X    return(TRUE);
  946. X}
  947. X.Lf
  948. X.LP
  949. XExercise:
  950. XRewrite example A so that it uses varying-length arrays and so that the
  951. X.LW netuser
  952. Xstructure contains the actual
  953. X.LW nu_gids
  954. Xarray body as in the example above.
  955. X.NH 3
  956. XDiscriminated Unions
  957. X.LP
  958. XThe XDR library supports discriminated unions.
  959. XA discriminated union is a C union and an
  960. X.LW enum_t
  961. Xvalue that selects an ``arm'' of the union.
  962. X.LS
  963. Xstruct xdr_discrim {
  964. X    enum_t value;
  965. X    bool_t (*proc)();
  966. X};
  967. X.sp.5
  968. Xbool_t xdr_union(xdrs, dscmp, unp, arms, defaultarm)
  969. X    XDR *xdrs;
  970. X    enum_t *dscmp;
  971. X    char *unp;
  972. X    struct xdr_discrim *arms;
  973. X    bool_t (*defaultarm)();  /* may equal NULL */
  974. X.Lf
  975. XFirst the routine translates the discriminant of the union located at 
  976. X.LW *dscmp .
  977. XThe discriminant is always an
  978. X.LW enum_t .
  979. XNext the union located at
  980. X.LW *unp
  981. Xis translated.
  982. XThe parameter
  983. X.LW arms
  984. Xis a pointer to an array of
  985. X.LW xdr_discrim
  986. Xstructures. 
  987. XEach structure contains an order pair of
  988. X.LW [value,proc] .
  989. XIf the union's discriminant is equal to the associated
  990. X.LW value ,
  991. Xthen the
  992. X.LW proc
  993. Xis called to translate the union.
  994. XThe end of the
  995. X.LW xdr_discrim
  996. Xstructure array is denoted by a routine of value
  997. X.LW NULL
  998. X(0).  If the discriminant is not found in the
  999. X.LW arms
  1000. Xarray, then the
  1001. X.LW defaultarm
  1002. Xprocedure is called if it is non-null;
  1003. Xotherwise the routine returns
  1004. X.LW FALSE .
  1005. X.LP
  1006. X.I "Example D"
  1007. X.LP
  1008. XSuppose the type of a union may be integer,
  1009. Xcharacter pointer (a string), or a
  1010. X.LW gnumbers
  1011. Xstructure.
  1012. XAlso, assume the union and its current type
  1013. Xare declared in a structure.
  1014. XThe declaration is:
  1015. X.LS
  1016. Xenum utype { INTEGER=1, STRING=2, GNUMBERS=3 };
  1017. X.sp.5
  1018. Xstruct u_tag {
  1019. X    enum utype utype;    /* the union's discriminant */
  1020. X    union {
  1021. X        int ival;
  1022. X        char *pval;
  1023. X        struct gnumbers gn;
  1024. X    } uval;
  1025. X};
  1026. X.Lf
  1027. XThe following constructs and XDR procedure (de)serialize
  1028. Xthe discriminated union:
  1029. X.LS
  1030. Xstruct xdr_discrim u_tag_arms[4] = {
  1031. X    { INTEGER, xdr_int },
  1032. X    { GNUMBERS, xdr_gnumbers }
  1033. X    { STRING, xdr_wrap_string },
  1034. X    { __dontcare__, NULL }
  1035. X    /* always terminate arms with a NULL xdr_proc */
  1036. X}
  1037. X.sp.5
  1038. Xbool_t
  1039. Xxdr_u_tag(xdrs, utp)
  1040. X    XDR *xdrs;
  1041. X    struct u_tag *utp;
  1042. X{
  1043. X    return(xdr_union(xdrs, &utp->utype, &utp->uval,
  1044. X        u_tag_arms, NULL));
  1045. X}
  1046. X.Lf
  1047. XThe routine
  1048. X.LW xdr_gnumbers()
  1049. Xwas presented in Section 2;
  1050. X.LW xdr_wrap_string()
  1051. Xwas presented in example C.
  1052. XThe default arm parameter to
  1053. X.LW xdr_union()
  1054. X(the last parameter) is
  1055. X.LW NULL
  1056. Xin this example.  Therefore the value of the union's discriminant
  1057. Xmay legally take on only values listed in the
  1058. X.LW u_tag_arms
  1059. Xarray.  This example also demonstrates that
  1060. Xthe elements of the arm's array do not need to be sorted.
  1061. X.LP
  1062. XIt is worth pointing out that the values of the discriminant
  1063. Xmay be sparse, though in this example they are not.
  1064. XIt is always good
  1065. Xpractice to assign explicitly integer values to each element of the
  1066. Xdiscriminant's type.
  1067. XThis practice both documents the external
  1068. Xrepresentation of the discriminant and guarantees that different
  1069. XC compilers emit identical discriminant values.
  1070. X.LP
  1071. XExercise: Implement
  1072. X.LW xdr_union()
  1073. Xusing the other primitives in this section.
  1074. X.NH 3
  1075. XPointers
  1076. X.LP
  1077. XIn C it is often convenient to put pointers
  1078. Xto another structure within a structure.
  1079. XThe primitive
  1080. X.LW xdr_reference()
  1081. Xmakes it easy to serialize, deserialize, and free
  1082. Xthese referenced structures.
  1083. X.LS
  1084. Xbool_t xdr_reference(xdrs, pp, size, proc)
  1085. X    XDR *xdrs;
  1086. X    char **pp;
  1087. X    u_int ssize;
  1088. X    bool_t (*proc)();
  1089. X.Lf
  1090. X.LP
  1091. XParameter
  1092. X.LW pp
  1093. Xis the address of
  1094. Xthe pointer to the structure;
  1095. Xparameter
  1096. X.LW ssize
  1097. Xis the size in bytes of the structure
  1098. X(use the C function
  1099. X.LW sizeof()
  1100. Xto obtain this value); and
  1101. X.LW proc
  1102. Xis the XDR routine that describes the structure.
  1103. XWhen decoding data, storage is allocated if
  1104. X.LW *pp
  1105. Xis
  1106. X.LW NULL .
  1107. X.LP
  1108. XThere is no need for a primitive
  1109. X.LW xdr_struct()
  1110. Xto describe structures within structures,
  1111. Xbecause pointers are always sufficient.
  1112. X.LP
  1113. XExercise: Implement
  1114. X.LW xdr_reference()
  1115. Xusing
  1116. X.LW xdr_array() .
  1117. XWarning:
  1118. X.LW xdr_reference()
  1119. Xand
  1120. X.LW xdr_array()
  1121. Xare NOT interchangeable external representations of data.
  1122. X.LP
  1123. X.I "Example E"
  1124. X.LP
  1125. XSuppose there is a structure containing a person's name
  1126. Xand a pointer to a
  1127. X.LW gnumbers
  1128. Xstructure containing the person's gross assets and liabilities.
  1129. XThe construct is:
  1130. X.LS
  1131. Xstruct pgn {
  1132. X    char *name;
  1133. X    struct gnumbers *gnp;
  1134. X};
  1135. X.Lf
  1136. XThe corresponding XDR routine for this structure is:
  1137. X.LS
  1138. Xbool_t
  1139. Xxdr_pgn(xdrs, pp)
  1140. X    XDR *xdrs;
  1141. X    struct pgn *pp;
  1142. X{
  1143. X    if (xdr_string(xdrs, &pp->name, NLEN) &&
  1144. X      xdr_reference(xdrs, &pp->gnp,
  1145. X      sizeof(struct gnumbers), xdr_gnumbers))
  1146. X        return(TRUE);
  1147. X    return(FALSE);
  1148. X}
  1149. X.Lf
  1150. X.NH 4
  1151. XPointer Semantics and XDR
  1152. X.LP
  1153. XIn many applications,
  1154. XC programmers attach double meaning to the values of a pointer.
  1155. XTypically the value
  1156. X.LW NULL
  1157. X(or zero) means data is not needed,
  1158. Xyet some application-specific interpretation applies.
  1159. XIn essence, the C programmer is encoding
  1160. Xa discriminated union efficiently
  1161. Xby overloading the interpretation of the value of a pointer.
  1162. XFor instance, in example E a
  1163. X.LW NULL
  1164. Xpointer value for
  1165. X.LW gnp
  1166. Xcould indicate that
  1167. Xthe person's assets and liabilities are unknown.
  1168. XThat is, the pointer value encodes two things:
  1169. Xwhether or not the data is known;
  1170. Xand if it is known, where it is located in memory.
  1171. XLinked lists are an extreme example of the use
  1172. Xof application-specific pointer interpretation.
  1173. X.LP
  1174. XThe primitive
  1175. X.LW xdr_reference()
  1176. Xcannot and does not attach any special
  1177. Xmeaning to a null-value pointer during serialization.
  1178. XThat is, passing an address of a pointer whose value is
  1179. X.LW NULL
  1180. Xto
  1181. X.LW xdr_reference()
  1182. Xwhen serialing data will most likely cause a memory fault and, on
  1183. X.UX ,
  1184. Xa core dump for debugging.
  1185. X.LP
  1186. XIt is the explicit responsibility of the programmer
  1187. Xto expand non-dereferenceable pointers into their specific semantics.
  1188. XThis usually involves describing data with a two-armed discriminated union.
  1189. XOne arm is used when the pointer is valid;
  1190. Xthe other is used when the pointer is invalid
  1191. X.LW NULL ). (
  1192. XSection 7 has an example (linked lists encoding) that deals
  1193. Xwith invalid pointer interpretation.
  1194. X.LP
  1195. XExercise:
  1196. XAfter reading Section 7, return here and extend example E so that
  1197. Xit can correctly deal with null pointer values.
  1198. X.LP
  1199. XExercise:
  1200. XUsing the
  1201. X.LW xdr_union() ,
  1202. X.LW xdr_reference()
  1203. Xand
  1204. X.LW xdr_void()
  1205. Xprimitives, implement a generic pointer handling primitive
  1206. Xthat implicitly deals with
  1207. X.LW NULL
  1208. Xpointers.  The XDR library does not provide such a primitive
  1209. Xbecause it does not want to give the illusion
  1210. Xthat pointers have meaning in the external world.
  1211. X.NH 2
  1212. XNon-filter Primitives
  1213. X.LP
  1214. XXDR streams can be manipulated with
  1215. Xthe primitives discussed in this section.
  1216. X.LS
  1217. Xu_int xdr_getpos(xdrs)
  1218. X    XDR *xdrs;
  1219. X.sp.5
  1220. Xbool_t xdr_setpos(xdrs, pos)
  1221. X    XDR *xdrs;
  1222. X    u_int pos;
  1223. X.sp.5
  1224. Xxdr_destroy(xdrs)
  1225. X    XDR *xdrs;
  1226. X.Lf
  1227. XThe routine
  1228. X.LW xdr_getpos()
  1229. Xreturns an unsigned integer
  1230. Xthat describes the current position in the data stream.
  1231. XWarning: In some XDR streams, the returned value of
  1232. X.LW xdr_getpos()
  1233. Xis meaningless;
  1234. Xthe routine returns a \-1 in this case
  1235. X(though \-1 should be a legitimate value).
  1236. X.LP
  1237. XThe routine
  1238. X.LW xdr_setpos()
  1239. Xsets a stream position to
  1240. X.LW pos .
  1241. XWarning: In some XDR streams, setting a position is impossible;
  1242. Xin such cases,
  1243. X.LW xdr_setpos()
  1244. Xwill return
  1245. X.LW FALSE .
  1246. XThis routine will also fail if the requested position is out-of-bounds.
  1247. XThe definition of bounds varies from stream to stream.
  1248. X.LP
  1249. XThe
  1250. X.LW xdr_destroy()
  1251. Xprimitive destroys the XDR stream.
  1252. XUsage of the stream
  1253. Xafter calling this routine is undefined.
  1254. X.NH 2
  1255. XXDR Operation Directions
  1256. X.LP
  1257. XAt times you may wish to optimize XDR routines by taking
  1258. Xadvantage of the direction of the operation \(em
  1259. X.LW XDR_ENCODE ,
  1260. X.LW XDR_DECODE ,
  1261. Xor
  1262. X.LW XDR_FREE .
  1263. XThe value
  1264. X.LW xdrs->x_op
  1265. Xalways contains the
  1266. Xdirection of the XDR operation.
  1267. XProgrammers are not encouraged to take advantage of this information.
  1268. XTherefore, no example is presented here.
  1269. XHowever, an example in Section 7
  1270. Xdemonstrates the usefulness of the
  1271. X.LW xdrs->x_op
  1272. Xfield.
  1273. X.bp
  1274. X.NH
  1275. XXDR Stream Access
  1276. X.LP
  1277. XAn XDR stream is obtained by calling the appropriate creation routine.
  1278. XThese creation routines take arguments that are tailored to the
  1279. Xspecific properties of the stream.
  1280. X.LP
  1281. XStreams currently exist for (de)serialization of data to or from
  1282. Xstandard I/O
  1283. X.LW FILE
  1284. Xstreams, TCP/IP connections and
  1285. X.UX
  1286. Xfiles, and memory.
  1287. XSection 5 documents the XDR object and how to make
  1288. Xnew XDR streams when they are required.
  1289. X.NH 2
  1290. XStandard I/O Streams
  1291. X.LP
  1292. XXDR streams can be interfaced to standard I/O using the
  1293. X.LW xdrstdio_create()
  1294. Xroutine as follows:
  1295. X.LS
  1296. X#include <stdio.h>
  1297. X#include <rpc/rpc.h>    /* xdr streams part of rpc */
  1298. X.sp.5
  1299. Xvoid
  1300. Xxdrstdio_create(xdrs, fp, x_op)
  1301. X    XDR *xdrs;
  1302. X    FILE *fp;
  1303. X    enum xdr_op x_op;
  1304. X.Lf
  1305. XThe routine
  1306. X.LW xdrstdio_create()
  1307. Xinitializes an XDR stream pointed to by
  1308. X.LW xdrs .
  1309. XThe XDR stream interfaces to the standard I/O library.
  1310. XParameter
  1311. X.LW fp
  1312. Xis an open file, and
  1313. X.LW x_op
  1314. Xis an XDR direction.
  1315. X.NH 2
  1316. XMemory Streams
  1317. X.LP
  1318. XMemory streams allow the streaming of data into or out of
  1319. Xa specified area of memory:
  1320. X.LS
  1321. X#include <rpc/rpc.h>
  1322. X.sp.5
  1323. Xvoid
  1324. Xxdrmem_create(xdrs, addr, len, x_op)
  1325. X    XDR *xdrs;
  1326. X    char *addr;
  1327. X    u_int len;
  1328. X    enum xdr_op x_op;
  1329. X.Lf
  1330. XThe routine
  1331. X.LW xdrmem_create()
  1332. Xinitializes an XDR stream in local memory.
  1333. XThe memory is pointed to by parameter
  1334. X.LW addr ;
  1335. Xparameter
  1336. X.LW len
  1337. Xis the length in bytes of the memory.
  1338. XThe parameters
  1339. X.LW xdrs
  1340. Xand
  1341. X.LW x_op
  1342. Xare identical to the corresponding parameters of
  1343. X.LW xdrstdio_create() .
  1344. XCurrently, the UDP/IP implementation of RPC uses
  1345. X.LW xdrmem_create() .
  1346. XComplete call or result messages are built in memory before calling the
  1347. X.LW sendto()
  1348. Xsystem routine.
  1349. X.NH 2
  1350. XRecord (TCP/IP) Streams
  1351. X.LP
  1352. XA record stream is an XDR stream built on top of
  1353. Xa record marking standard that is built on top of the
  1354. X.UX
  1355. Xfile or 4.2 BSD connection interface.
  1356. X.LS
  1357. X#include <rpc/rpc.h>    /* xdr streams part of rpc */
  1358. X.sp.5
  1359. Xxdrrec_create(xdrs,
  1360. X  sendsize, recvsize, iohandle, readproc, writeproc)
  1361. X    XDR *xdrs;
  1362. X    u_int sendsize, recvsize;
  1363. X    char *iohandle;
  1364. X    int (*readproc)(), (*writeproc)();
  1365. X.Lf
  1366. XThe routine
  1367. X.LW xdrrec_create()
  1368. Xprovides an XDR stream interface that allows for a bidirectional,
  1369. Xarbitrarily long sequence of records.
  1370. XThe contents of the records are meant to be data in XDR form.
  1371. XThe stream's primary use is for interfacing RPC to TCP connections.
  1372. XHowever, it can be used to stream data into or out of normal
  1373. X.UX
  1374. Xfiles.
  1375. X.LP
  1376. XThe parameter
  1377. X.LW xdrs
  1378. Xis similar to the corresponding parameter described above.
  1379. XThe stream does its own data buffering similar to that of standard I/O.
  1380. XThe parameters
  1381. X.LW sendsize
  1382. Xand
  1383. X.LW recvsize
  1384. Xdetermine the size in bytes of the output and input buffers, respectively;
  1385. Xif their values are zero (0), then predetermined defaults are used.
  1386. XWhen a buffer needs to be filled or flushed, the routine
  1387. X.LW readproc
  1388. Xor
  1389. X.LW writeproc
  1390. Xis called, respectively.
  1391. XThe usage and behavior of these
  1392. Xroutines are similar to the
  1393. X.UX
  1394. Xsystem calls
  1395. X.LW read()
  1396. Xand
  1397. X.LW write() .
  1398. XHowever,
  1399. Xthe first parameter to each of these routines is the opaque parameter
  1400. X.LW iohandle .
  1401. XThe other two parameters
  1402. X.LW buf "" (
  1403. Xand
  1404. X.LW nbytes )
  1405. Xand the results
  1406. X(byte count) are identical to the system routines.
  1407. XIf
  1408. X.LW xxx
  1409. Xis
  1410. X.LW readproc
  1411. Xor
  1412. X.LW writeproc ,
  1413. Xthen it has the following form:
  1414. X.LS
  1415. X/*
  1416. X * returns the actual number of bytes transferred.
  1417. X * -1 is an error
  1418. X */
  1419. Xint
  1420. Xxxx(iohandle, buf, len)
  1421. X    char *iohandle;
  1422. X    char *buf;
  1423. X    int nbytes;
  1424. X.Lf
  1425. XThe XDR stream provides means for delimiting records in the byte stream.
  1426. XThe implementation details of delimiting records in a stream
  1427. Xare discussed in appendix 1.
  1428. XThe primitives that are specific to record streams are as follows:
  1429. X.LS
  1430. Xbool_t
  1431. Xxdrrec_endofrecord(xdrs, flushnow)
  1432. X    XDR *xdrs;
  1433. X    bool_t flushnow;
  1434. X.sp.5
  1435. Xbool_t
  1436. Xxdrrec_skiprecord(xdrs)
  1437. X    XDR *xdrs;
  1438. X.sp.5
  1439. Xbool_t
  1440. Xxdrrec_eof(xdrs)
  1441. X    XDR *xdrs;
  1442. X.Lf
  1443. XThe routine
  1444. X.LW xdrrec_endofrecord()
  1445. Xcauses the current outgoing data to be marked as a record.
  1446. XIf the parameter
  1447. X.LW flushnow
  1448. Xis
  1449. X.LW TRUE ,
  1450. Xthen the stream's
  1451. X.LW writeproc()
  1452. Xwill be called; otherwise,
  1453. X.LW writeproc()
  1454. Xwill be called when the output buffer has been filled.
  1455. X.LP
  1456. XThe routine
  1457. X.LW xdrrec_skiprecord()
  1458. Xcauses an input stream's position to be moved past
  1459. Xthe current record boundary and onto the
  1460. Xbeginning of the next record in the stream.
  1461. X.LP
  1462. XIf there is no more data in the stream's input buffer,
  1463. Xthen the routine
  1464. X.LW xdrrec_eof()
  1465. Xreturns
  1466. X.LW TRUE .
  1467. XThat is not to say that there is no more data
  1468. Xin the underlying file descriptor.
  1469. X.bp
  1470. X.NH
  1471. XXDR Stream Implementation
  1472. X.LP
  1473. XThis section provides the abstract data types needed
  1474. Xto implement new instances of XDR streams.
  1475. X.NH 2
  1476. XThe XDR Object
  1477. X.LP
  1478. XThe following structure defines the interface to an XDR stream:
  1479. X.LS
  1480. Xenum xdr_op { XDR_ENCODE=0, XDR_DECODE=1, XDR_FREE=2 };
  1481. X.sp.5
  1482. Xtypedef struct {
  1483. X    enum xdr_op x_op;    /* operation; fast added param */
  1484. X    struct xdr_ops {
  1485. X        bool_t  (*x_getlong)();  /* get long from stream */
  1486. X        bool_t  (*x_putlong)();  /* put long to stream */
  1487. X        bool_t  (*x_getbytes)(); /* get bytes from stream */
  1488. X        bool_t  (*x_putbytes)(); /* put bytes to stream */
  1489. X        u_int   (*x_getpostn)(); /* return stream offset */
  1490. X        bool_t  (*x_setpostn)(); /* reposition offset */
  1491. X        caddr_t (*x_inline)();   /* ptr to buffered data */
  1492. X        VOID    (*x_destroy)();  /* free private area */
  1493. X    } *x_ops;
  1494. X    caddr_t    x_public;    /* users' data */
  1495. X    caddr_t    x_private;    /* pointer to private data */
  1496. X    caddr_t    x_base;        /* private for position info */
  1497. X    int        x_handy;    /* extra private word */
  1498. X} XDR;
  1499. X.Lf
  1500. XThe
  1501. X.LW x_op
  1502. Xfield is the current operation being performed on the stream.
  1503. XThis field is important to the XDR primitives,
  1504. Xbut should not affect a stream's implementation.
  1505. XThat is, a stream's implementation should not depend
  1506. Xon this value.
  1507. XThe fields
  1508. X.LW x_private ,
  1509. X.LW x_base ,
  1510. Xand
  1511. X.LW x_handy
  1512. Xare private to the particular
  1513. Xstream's implementation.
  1514. XThe field
  1515. X.LW x_public
  1516. Xis for the XDR client and should never be used by
  1517. Xthe XDR stream implementations or the XDR primitives.
  1518. X.LP
  1519. XMacros for accessing  operations
  1520. X.LW x_getpostn() ,
  1521. X.LW x_setpostn() ,
  1522. Xand
  1523. X.LW x_destroy()
  1524. Xwere defined in Section 3.6.
  1525. XThe operation
  1526. X.LW x_inline()
  1527. Xtakes two parameters:
  1528. Xan XDR *, and an unsigned integer, which is a byte count.
  1529. XThe routine returns a pointer to a piece of
  1530. Xthe stream's internal buffer.
  1531. XThe caller can then use the buffer segment for any purpose.
  1532. XFrom the stream's point of view, the bytes in the
  1533. Xbuffer segment have been consumed or put.
  1534. XThe routine may return
  1535. X.LW NULL
  1536. Xif it cannot return a buffer segment of the requested size.
  1537. X(The
  1538. X.LW x_inline
  1539. Xroutine is for cycle squeezers.
  1540. XUse of the resulting buffer is not data-portable.
  1541. XUsers are encouraged not to use this feature.) 
  1542. X.LP
  1543. XThe operations
  1544. X.LW x_getbytes()
  1545. Xand
  1546. X.LW x_putbytes()
  1547. Xblindly get and put sequences of bytes
  1548. Xfrom or to the underlying stream;
  1549. Xthey return
  1550. X.LW TRUE
  1551. Xif they are successful, and
  1552. X.LW FALSE
  1553. Xotherwise.  The routines have identical parameters (replace
  1554. X.LW xxx ):
  1555. X.LS
  1556. Xbool_t
  1557. Xxxxbytes(xdrs, buf, bytecount)
  1558. X    XDR *xdrs;
  1559. X    char *buf;
  1560. X    u_int bytecount;
  1561. X.Lf
  1562. XThe operations
  1563. X.LW x_getlong()
  1564. Xand
  1565. X.LW x_putlong()
  1566. Xreceive and put
  1567. Xlong numbers from and to the data stream.
  1568. XIt is the responsibility of these routines
  1569. Xto translate the numbers between the machine representation
  1570. Xand the (standard) external representation.
  1571. XThe
  1572. X.UX
  1573. Xprimitives
  1574. X.LW htonl()
  1575. Xand
  1576. X.LW ntohl()
  1577. Xcan be helpful in accomplishing this.
  1578. XSection 6 defines the standard representation of numbers.
  1579. XThe higher-level XDR implementation assumes that
  1580. Xsigned and unsigned long integers contain the same number of bits,
  1581. Xand that nonnegative integers
  1582. Xhave the same bit representations as unsigned integers.
  1583. XThe routines return
  1584. X.I TRUE
  1585. Xif they succeed, and
  1586. X.LW FALSE
  1587. Xotherwise.  They have identical parameters:
  1588. X.LS
  1589. Xbool_t
  1590. Xxxxlong(xdrs, lp)
  1591. X    XDR *xdrs;
  1592. X    long *lp;
  1593. X.Lf
  1594. XImplementors of new XDR streams must make an XDR structure
  1595. X(with new operation routines) available to clients,
  1596. Xusing some kind of create routine.
  1597. X.bp
  1598. X.NH
  1599. XXDR Standard
  1600. X.LP
  1601. XThis section defines the external data representation standard.
  1602. XThe standard is independent of languages,
  1603. Xoperating systems and hardware architectures.
  1604. XOnce data is shared among machines, it should not matter that the data
  1605. Xwas produced on a Sun, but is consumed by a VAX (or vice versa).
  1606. XSimilarly the choice of operating systems should have no influence
  1607. Xon how the data is represented externally.
  1608. XFor programming languages,
  1609. Xdata produced by a C program should be readable
  1610. Xby a Fortran or Pascal program.
  1611. X.LP
  1612. XThe external data representation standard depends on the assumption that
  1613. Xbytes (or octets) are portable.
  1614. XA byte is defined to be eight bits of data.
  1615. XIt is assumed that hardware
  1616. Xthat encodes bytes onto various media
  1617. Xwill preserve the bytes' meanings
  1618. Xacross hardware boundaries.
  1619. XFor example, the Ethernet standard suggests that bytes be
  1620. Xencoded ``little endian'' style.
  1621. XBoth Sun and VAX hardware implementations
  1622. Xadhere to the standard.
  1623. X.LP
  1624. XThe XDR standard also suggests a language used to describe data.
  1625. XThe language is a bastardized C;
  1626. Xit is a data description language, not a programming language.
  1627. X(The Xerox Courier Standard uses bastardized Mesa
  1628. Xas its data description language.)
  1629. X.NH 2
  1630. XBasic Block Size
  1631. X.LP
  1632. XThe representation of all items requires
  1633. Xa multiple of four bytes (or 32 bits) of data.
  1634. XThe bytes are numbered
  1635. X$0$ through $n-1$, where $(n ~ \fRmod\fP ~ 4) = 0$.
  1636. XThe bytes are read or written to some byte stream
  1637. Xsuch that byte $m$ always precedes byte $m+1$.
  1638. X.NH 2
  1639. XInteger
  1640. X.LP
  1641. XAn XDR signed integer is a 32-bit datum
  1642. Xthat encodes an integer in the range
  1643. X.LW [-2147483648,2147483647] . 
  1644. XThe integer is represented in two's complement notation. 
  1645. XThe most and least significant bytes are 0 and 3, respectively.
  1646. XThe data description of integers is
  1647. X.LW integer .
  1648. X.NH 2
  1649. XUnsigned Integer
  1650. X.LP
  1651. XAn XDR unsigned integer is a 32-bit datum
  1652. Xthat encodes a nonnegative integer in the range
  1653. X.LW [0,4294967295] .
  1654. XIt is represented by an unsigned binary number whose most
  1655. Xand least significant bytes are 0 and 3, respectively.
  1656. XThe data description of unsigned integers is
  1657. X.LW unsigned .
  1658. X.NH 2
  1659. XEnumerations
  1660. X.LP
  1661. XEnumerations have the same representation as integers.
  1662. XEnumerations are handy for describing subsets of the integers.
  1663. XThe data description of enumerated data is as follows:
  1664. X.LS
  1665. Xtypedef enum { name = value, .... } type-name;
  1666. X.Lf
  1667. XFor example the three colors red, yellow and blue
  1668. Xcould be described by an enumerated type:
  1669. X.LS
  1670. Xtypedef enum { RED = 2, YELLOW = 3, BLUE = 5 } colors;
  1671. X.Lf
  1672. X.NH 2
  1673. XBooleans
  1674. X.LP
  1675. XBooleans are important enough and occur frequently enough
  1676. Xto warrant their own explicit type in the standard.
  1677. XBoolean is an enumeration with the
  1678. Xfollowing form:
  1679. X.LS
  1680. Xtypedef enum { FALSE = 0, TRUE = 1 } boolean;
  1681. X.Lf
  1682. X.NH 2
  1683. XHyper Integer and Hyper Unsigned
  1684. X.LP
  1685. XThe standard also defines 64-bit (8-byte) numbers called 
  1686. X.LW "hyper integer"
  1687. Xand
  1688. X.LW "hyper unsigned" .
  1689. XTheir representations are the obvious extensions of 
  1690. Xthe integer and unsigned defined above.
  1691. XThe most and least significant bytes are 0 and 7, respectively.
  1692. X.NH 2
  1693. XFloating Point and Double Precision
  1694. X.LP
  1695. XThe standard defines the encoding for the floating point data types
  1696. X.LW float
  1697. X(32 bits or 4 bytes) and
  1698. X.LW double
  1699. X(64 bits or 8 bytes).
  1700. XThe encoding used is the IEEE standard for normalized
  1701. Xsingle- and double-precision floating point numbers.
  1702. XSee the IEEE floating point standard for more information.
  1703. XThe standard encodes the following three fields,
  1704. Xwhich describe the floating point number:
  1705. X.IP \fIS\fP
  1706. XThe sign of the number.
  1707. XValues 0 and 1 represent 
  1708. Xpositive and negative, respectively.
  1709. X.IP \fIE\fP
  1710. XThe exponent of the number, base 2.
  1711. XFloats devote 8 bits to this field,
  1712. Xwhile doubles devote 11 bits.
  1713. XThe exponents for float and double are
  1714. Xbiased by 127 and 1023, respectively.
  1715. X.IP \fIF\fP
  1716. XThe fractional part of the number's mantissa, base 2.
  1717. XFloats devote 23 bits to this field,
  1718. Xwhile doubles devote 52 bits.
  1719. X.LP
  1720. XTherefore, the floating point number is described by:
  1721. X.EQ
  1722. X(-1) sup S * 2 sup { E - Bias } * 1.F
  1723. X.EN
  1724. X.LP
  1725. XJust as the most and least significant bytes of a number are 0 and 3,
  1726. Xthe most and least significant bits of
  1727. Xa single-precision floating point number are 0 and 31.
  1728. XThe beginning bit (and most significant bit) offsets
  1729. Xof $S$, $E$, and $F$ are 0, 1, and 9, respectively.
  1730. X.LP
  1731. XDoubles have the analogous extensions.
  1732. XThe beginning bit (and
  1733. Xmost significant bit) offsets of $S$, $E$, and $F$
  1734. Xare 0, 1, and 12, respectively.
  1735. X.LP
  1736. XThe IEEE specification should be consulted concerning the encoding for
  1737. Xsigned zero, signed infinity (overflow), and denormalized numbers (underflow).
  1738. XUnder IEEE specifications, the ``NaN'' (not a number)
  1739. Xis system dependent and should not be used.
  1740. X.NH 2
  1741. XOpaque Data
  1742. X.LP
  1743. XAt times fixed-sized uninterpreted data
  1744. Xneeds to be passed among machines.
  1745. XThis data is called
  1746. X.LW opaque
  1747. Xand is described as:
  1748. X.LS
  1749. Xtypedef opaque type-name[n];
  1750. Xopaque name[n];
  1751. X.Lf
  1752. Xwhere
  1753. X.LW n
  1754. Xis the (static) number of bytes necessary to contain the opaque data.
  1755. XIf
  1756. X.LW n
  1757. Xis not a multiple of four, then the
  1758. X.LW n
  1759. Xbytes are followed by enough (up to 3) zero-valued bytes
  1760. Xto make the total byte count of the opaque object a multiple of four.
  1761. X.NH 2
  1762. XCounted Byte Strings
  1763. X.LP
  1764. XThe standard defines a string of $n$ (numbered $0$ through $n-1$)
  1765. Xbytes to be the number $n$ encoded as
  1766. X.LW unsigned ,
  1767. Xand followed by the $n$ bytes of the string.
  1768. XIf $n$ is not a multiple of four,
  1769. Xthen the $n$ bytes are followed by
  1770. Xenough (up to 3) zero-valued bytes
  1771. Xto make the total byte count a multiple of four.
  1772. XThe data description of strings is as follows:
  1773. X.LS
  1774. Xtypedef string type-name<N>;
  1775. Xtypedef string type-name<>;
  1776. Xstring name<N>;
  1777. Xstring name<>;
  1778. X.Lf
  1779. XNote that the data description language uses angle brackets (< and >)
  1780. Xto denote anything that is varying-length
  1781. X(as opposed to square brackets to denote fixed-length sequences of data).
  1782. X.LP
  1783. XThe constant
  1784. X.LW N
  1785. Xdenotes an upper bound of the number of bytes that a
  1786. Xstring may contain.
  1787. XIf
  1788. X.LW N
  1789. Xis not specified, it is assumed to be $2 sup 32 - 1$,
  1790. Xthe maximum length.
  1791. XThe constant
  1792. X.LW N
  1793. Xwould normally be found in a protocol specification.
  1794. XFor example, a filing protocol may state
  1795. Xthat a file name can be no longer than 255 bytes, such as:
  1796. X.LS
  1797. Xstring filename<255>;
  1798. X.Lf
  1799. X.LP
  1800. XThe XDR specification does not say what the
  1801. Xindividual bytes of a string represent;
  1802. Xthis important information is left to higher-level specifications.
  1803. XA reasonable default is to assume
  1804. Xthat the bytes encode ASCII characters.
  1805. X.NH 2
  1806. XFixed Arrays
  1807. X.LP
  1808. XThe data description for fixed-size arrays of
  1809. Xhomogeneous elements is as follows:
  1810. X.LS
  1811. Xtypedef elementtype type-name[n];
  1812. Xelementtype name[n];
  1813. X.Lf
  1814. XFixed-size arrays of elements numbered $0$ through $n-1$
  1815. Xare encoded by individually encoding the elements of the array
  1816. Xin their natural order, $0$ through $n-1$.
  1817. X.NH 2
  1818. XCounted Arrays
  1819. X.LP
  1820. XCounted arrays provide the ability to encode varyiable-length arrays
  1821. Xof homogeneous elements.
  1822. XThe array is encoded as:
  1823. Xthe element count $n$ (an unsigned integer),
  1824. Xfollowed by the encoding of each of the array's elements,
  1825. Xstarting with element $0$ and progressing through element $n-1$.
  1826. XThe data description for counted arrays
  1827. Xis similar to that of counted strings:
  1828. X.LS
  1829. Xtypedef elementtype type-name<N>;
  1830. Xtypedef elementtype type-name<>;
  1831. Xelementtype name<N>;
  1832. Xelementtype name<>;
  1833. X.Lf
  1834. XAgain, the constant
  1835. X.LW N
  1836. Xspecifies the maximum acceptable
  1837. Xelement count of an array; if
  1838. X.LW N
  1839. Xis  not specified, it is assumed to be $2 sup 32 - 1$.
  1840. X.NH 2
  1841. XStructures
  1842. X.LP
  1843. XThe data description for structures is very similar to
  1844. Xthat of standard C:
  1845. X.LS
  1846. Xtypedef struct {
  1847. X    component-type component-name;
  1848. X    ...
  1849. X} type-name;
  1850. X.Lf
  1851. XThe components of the structure are encoded 
  1852. Xin the order of their declaration in the structure.
  1853. X.NH 2
  1854. XDiscriminated Unions
  1855. X.LP
  1856. XA discriminated union is a type composed of a discriminant followed by a type
  1857. Xselected from a set of prearranged types according to the value of the
  1858. Xdiscriminant.
  1859. XThe type of the discriminant is always an enumeration.
  1860. XThe component types are called ``arms'' of the union.
  1861. XThe discriminated union is encoded as its discriminant followed by
  1862. Xthe encoding of the implied arm.
  1863. XThe data description for discriminated unions is as follows:
  1864. X.LS
  1865. Xtypedef union switch (discriminant-type) {
  1866. X    discriminant-value: arm-type;
  1867. X    ...
  1868. X    default: default-arm-type;
  1869. X} type-name;
  1870. X.Lf
  1871. XThe default arm is optional.
  1872. XIf it is not specified, then a valid
  1873. Xencoding of the union cannot take on unspecified discriminant values.
  1874. XMost specifications neither need nor use default arms.
  1875. X.NH 2
  1876. XMissing Specifications
  1877. X.LP
  1878. XThe standard lacks representations for bit fields and bitmaps,
  1879. Xsince the standard is based on bytes.
  1880. XThis is not to say that no specification should be attempted.
  1881. X.NH 2
  1882. XLibrary Primitive / XDR Standard Cross Reference
  1883. X.LP
  1884. XThe following table describes the association between
  1885. Xthe C library primitives discussed in Section 3,
  1886. Xand the standard data types defined in this section:
  1887. X.LP
  1888. X.TS
  1889. Xbox;
  1890. XcfBI s s
  1891. XcfI cfI cfI
  1892. XrfL | cfL | l.
  1893. X.sp.1
  1894. XPrimitives and Data Types
  1895. X.sp.1
  1896. X_
  1897. XC Primitive    XDR Type    Sections
  1898. X_
  1899. Xxdr_int
  1900. Xxdr_long    integer    3.1, 6.2
  1901. Xxdr_short
  1902. X_
  1903. Xxdr_u_int
  1904. Xxdr_u_long    unsigned    3.1, 6.3
  1905. Xxdr_u_short
  1906. X_
  1907. X-    hyper integer    6.6
  1908. X    hyper unsigned
  1909. X_
  1910. Xxdr_float    float    3.2, 6.7
  1911. X_
  1912. Xxdr_double    double    3.2, 6.7
  1913. X_
  1914. Xxdr_enum    enum_t    3.3, 6.4
  1915. X_
  1916. Xxdr_bool    bool_t    3.3, 6.5
  1917. X_
  1918. Xxdr_string    string    3.5.1, 6.9
  1919. Xxdr_bytes        3.5.2
  1920. X_
  1921. Xxdr_array    \fR(varying arrays)\fP    3.5.3, 6.11
  1922. X_
  1923. X-    \fR(fixed arrays)\fP    3.5.5, 6.10
  1924. X_
  1925. Xxdr_opaque    opaque    3.5.4, 6.8
  1926. X_
  1927. Xxdr_union    union    3.5.6, 6.13
  1928. X_
  1929. Xxdr_reference    -    3.5.7
  1930. X_
  1931. X-    struct    6.6
  1932. X.TE
  1933. X.TN "Primitives and Data Types"
  1934. X.bp
  1935. X.NH
  1936. XAdvanced Topics
  1937. X.LP
  1938. XThis section describes techniques for passing data structures
  1939. Xthat are not covered in the preceding sections.
  1940. XSuch structures include linked lists (of arbitrary lengths).
  1941. XUnlike the simpler examples covered in the earlier sections,
  1942. Xthe following examples are written using both
  1943. Xthe XDR C library routines and the XDR data description language.
  1944. XSection 6 describes the XDR data definition language used below.
  1945. X.NH 2
  1946. XLinked Lists
  1947. X.LP
  1948. XThe last example in Section 2 presented a C data structure and its
  1949. Xassociated XDR routines for a person's gross assets and liabilities.
  1950. XThe example is duplicated below:
  1951. X.LS
  1952. Xstruct gnumbers {
  1953. X    long g_assets;
  1954. X    long g_liabilities;
  1955. X};
  1956. X.sp.5
  1957. Xbool_t
  1958. Xxdr_gnumbers(xdrs, gp)
  1959. X    XDR *xdrs;
  1960. X    struct gnumbers *gp;
  1961. X{
  1962. X    if (xdr_long(xdrs, &(gp->g_assets)))
  1963. X        return(xdr_long(xdrs, &(gp->g_liabilities)));
  1964. X    return(FALSE);
  1965. X}
  1966. X.Lf
  1967. XNow assume that we wish to implement a linked list of such information.
  1968. XA data structure could be constructed as follows:
  1969. X.LS
  1970. Xtypedef struct gnnode {
  1971. X    struct gnumbers gn_numbers;
  1972. X    struct gnnode *nxt;
  1973. X};
  1974. X.sp.5
  1975. Xtypedef struct gnnode *gnumbers_list;
  1976. X.Lf
  1977. XThe head of the linked list can be thought of as the data object;
  1978. Xthat is, the head is not merely a convenient shorthand for a structure.
  1979. XSimilarly the
  1980. X.LW nxt
  1981. Xfield is used to indicate whether or not the object has terminated.
  1982. XUnfortunately, if the object continues, the
  1983. X.LW nxt
  1984. Xfield is also the address
  1985. Xof where it continues.
  1986. XThe link addresses carry no useful information when
  1987. Xthe object is serialized.
  1988. X.LP
  1989. XThe XDR data description of this linked list is described by the
  1990. Xrecursive type declaration of gnumbers_list:
  1991. X.LS
  1992. Xstruct gnumbers {
  1993. X    unsigned g_assets;
  1994. X    unsigned g_liabilities;
  1995. X};
  1996. X.Lf
  1997. X.LS
  1998. Xtypedef union switch (boolean) {
  1999. X    case TRUE: struct {
  2000. X        struct gnumbers current_element;
  2001. X        gnumbers_list rest_of_list;
  2002. X    };
  2003. X    case FALSE: struct {};
  2004. X} gnumbers_list;
  2005. X.Lf
  2006. XIn this description,
  2007. Xthe boolean indicates whether there is more data following it.
  2008. XIf the boolean is
  2009. X.LW FALSE ,
  2010. Xthen it is the last data field of the structure.
  2011. XIf it is
  2012. X.LW TRUE ,
  2013. Xthen it is followed by a
  2014. X.LW gnumbers
  2015. Xstructure and (recursively) by a
  2016. X.LW gnumbers_list
  2017. X(the rest of the object).
  2018. XNote that the C declaration has no boolean explicitly declared in it
  2019. X(though the
  2020. X.LW nxt
  2021. Xfield implicitly carries the information), while
  2022. Xthe XDR data description has no pointer explicitly declared in it.
  2023. X.LP
  2024. XHints for writing a set of XDR routines to successfully (de)serialize
  2025. Xa linked list of entries can be taken
  2026. Xfrom the XDR description of the pointer-less data.
  2027. XThe set consists of the mutually recursive routines
  2028. X.LW xdr_gnumbers_list ,
  2029. X.LW xdr_wrap_list ,
  2030. Xand
  2031. X.LW xdr_gnnode .
  2032. X.LS
  2033. Xbool_t
  2034. Xxdr_gnnode(xdrs, gp)
  2035. X    XDR *xdrs;
  2036. X    struct gnnode *gp;
  2037. X{
  2038. X    return(xdr_gnumbers(xdrs, &(gp->gn_numbers)) &&
  2039. X        xdr_gnumbers_list(xdrs, &(gp->nxt)) );
  2040. X}
  2041. X.Lf
  2042. SHAR_EOF
  2043. if test 49809 -ne "`wc -c < 'rpc/doc/xdr.spec.p1'`"
  2044. then
  2045.     echo shar: "error transmitting 'rpc/doc/xdr.spec.p1'" '(should have been 49809 characters)'
  2046. fi
  2047. chmod 444 'rpc/doc/xdr.spec.p1'
  2048. fi
  2049. exit 0
  2050. #    End of shell archive
  2051.